Skip to content

同步创建浏览器

概述

同步创建浏览器是FBro提供的一种在UI线程中直接创建浏览器实例的方法。与异步创建不同,同步创建会立即返回浏览器对象,但必须在CEF的UI线程中执行。

核心概念

线程要求

  • 必须在UI线程执行:同步创建浏览器的操作必须在CEF的UI线程中进行
  • 任务投递机制:使用FBroSharpTaskRunner.CefPostTask将创建任务投递到UI线程
  • 立即返回:创建成功后立即返回浏览器实例,无需等待回调

适用场景

  • 需要立即获取浏览器实例的场景
  • 在已知UI线程环境下的浏览器创建
  • 批量创建浏览器时的同步控制

浏览器事件回调类详解

BrowserEvent基础结构

同步创建浏览器同样需要使用BrowserEvent事件回调类。以下是一个专门为同步创建优化的事件处理器:

csharp
using FBroSharp;
using FBroSharp.Const;
using FBroSharp.DataType;
using FBroSharp.Event;
using FBroSharp.Lib;
using FBroSharp.Value;
using System;
using System.Collections.Generic;
using System.Reflection;
using FBroSharp.Callback;
using System.IO;

namespace SyncBrowserExample
{
    /// <summary>
    /// 同步创建浏览器的事件处理器
    /// 针对同步创建场景优化的事件回调类
    /// </summary>
    public class SyncBrowserEvent : FBroSharpBrowserEvent
    {
        private readonly Action<IFBroSharpBrowser> onCreated;
        private readonly Action<IFBroSharpBrowser> onClosed;
        private readonly string browserPurpose;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="onCreated">浏览器创建完成回调</param>
        /// <param name="onClosed">浏览器关闭回调</param>
        /// <param name="purpose">浏览器用途描述</param>
        public SyncBrowserEvent(Action<IFBroSharpBrowser> onCreated = null, Action<IFBroSharpBrowser> onClosed = null, string purpose = "")
        {
            this.onCreated = onCreated;
            this.onClosed = onClosed;
            this.browserPurpose = purpose;
        }

        #region 核心生命周期事件

        /// <summary>
        /// 浏览器创建完成事件
        /// 同步创建场景下,此事件在浏览器可用时立即触发
        /// </summary>
        public override void OnAfterCreated(IFBroSharpBrowser browser, IFBroSharpDictionaryValue extrainfo)
        {
            Console.WriteLine($"[同步浏览器创建] ID: {browser.GetIdentifier()}, 用途: {browserPurpose}");
            
            try
            {
                // 立即配置浏览器
                ConfigureSyncBrowser(browser);
                
                // 执行自定义创建完成回调
                onCreated?.Invoke(browser);
                
                Console.WriteLine($"同步浏览器配置完成: {browser.GetIdentifier()}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"同步浏览器配置失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 浏览器关闭前事件
        /// </summary>
        public override void OnBeforeClose(IFBroSharpBrowser browser)
        {
            Console.WriteLine($"[同步浏览器关闭] ID: {browser.GetIdentifier()}");
            
            try
            {
                // 执行自定义关闭回调
                onClosed?.Invoke(browser);
                
                // 清理同步创建的资源
                CleanupSyncResources(browser);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"同步浏览器清理失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 控制浏览器关闭行为
        /// </summary>
        public override bool DoClose(IFBroSharpBrowser browser)
        {
            Console.WriteLine($"[同步浏览器] 请求关闭: {browser.GetIdentifier()}");
            return false; // 允许关闭
        }

        #endregion

        #region 页面加载事件

        /// <summary>
        /// 加载状态变化 - 针对同步场景优化
        /// </summary>
        public override void OnLoadingStateChange(IFBroSharpBrowser browser, bool isLoading, bool canGoBack, bool canGoForward)
        {
            string status = isLoading ? "加载中" : "加载完成";
            Console.WriteLine($"[同步浏览器-{browser.GetIdentifier()}] {status}");
            
            if (!isLoading)
            {
                // 页面加载完成,可以立即执行后续操作
                OnSyncPageLoadCompleted(browser);
            }
        }

        /// <summary>
        /// 页面加载完成处理
        /// </summary>
        private void OnSyncPageLoadCompleted(IFBroSharpBrowser browser)
        {
            try
            {
                // 注入一些有用的JavaScript工具
                string utilityJS = @"
                    // 添加同步浏览器标识
                    window.FBroSyncBrowser = true;
                    window.FBroBrowserId = " + browser.GetIdentifier() + @";
                    
                    // 页面加载完成标记
                    console.log('FBro同步浏览器页面加载完成, ID: ' + window.FBroBrowserId);
                    
                    // 添加实用工具函数
                    window.FBroUtils = {
                        getBrowserId: function() { return window.FBroBrowserId; },
                        getPageInfo: function() {
                            return {
                                url: window.location.href,
                                title: document.title,
                                browserId: window.FBroBrowserId
                            };
                        }
                    };
                ";
                
                browser.GetMainFrame().ExecuteJavaScript(utilityJS, "", 0);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"同步浏览器页面初始化失败: {ex.Message}");
            }
        }

        #endregion

        #region 右键菜单增强

        /// <summary>
        /// 自定义右键菜单 - 同步浏览器版本
        /// </summary>
        public override void OnBeforeContextMenu(IFBroSharpBrowser browser, IFBroSharpFrame frame, IFBroSharpContextMenuParams menu_params, IFBroSharpMenuModel model)
        {
            // 添加同步浏览器专用菜单
            model.AddSeparator();
            var syncMenu = model.AddSubMenu(20000, "同步浏览器工具");
            
            syncMenu.AddItem(20001, $"浏览器ID: {browser.GetIdentifier()}");
            syncMenu.AddSeparator();
            syncMenu.AddItem(20002, "获取页面信息");
            syncMenu.AddItem(20003, "执行测试脚本");
            syncMenu.AddItem(20004, "开发者工具");
        }

        /// <summary>
        /// 处理自定义菜单命令
        /// </summary>
        public override bool OnContextMenuCommand(IFBroSharpBrowser browser, IFBroSharpFrame frame, IFBroSharpContextMenuParams menu_params, int command_id, FBroSharpEventFlags event_flags)
        {
            switch (command_id)
            {
                case 20002: // 获取页面信息
                    GetSyncBrowserPageInfo(browser, frame);
                    return true;
                    
                case 20003: // 执行测试脚本
                    ExecuteSyncTestScript(browser, frame);
                    return true;
                    
                case 20004: // 开发者工具
                    browser.ShowDevTools("同步浏览器开发工具", IntPtr.Zero, 0, 0, 1200, 800, default, default, default, default);
                    return true;
            }
            
            return false;
        }

        #endregion

        #region 辅助方法

        /// <summary>
        /// 配置同步创建的浏览器
        /// </summary>
        private void ConfigureSyncBrowser(IFBroSharpBrowser browser)
        {
            // 设置合适的缩放级别
            browser.SetZoomLevel(0.0);
            
            // 可以在这里添加其他同步浏览器的特殊配置
            Console.WriteLine($"同步浏览器基础配置完成: {browser.GetIdentifier()}");
        }

        /// <summary>
        /// 获取同步浏览器页面信息
        /// </summary>
        private void GetSyncBrowserPageInfo(IFBroSharpBrowser browser, IFBroSharpFrame frame)
        {
            try
            {
                string jsCode = @"
                    var info = window.FBroUtils ? window.FBroUtils.getPageInfo() : {
                        url: window.location.href,
                        title: document.title,
                        browserId: 'unknown'
                    };
                    
                    alert('同步浏览器信息:\n' + 
                          'ID: ' + info.browserId + '\n' +
                          'URL: ' + info.url + '\n' + 
                          'Title: ' + info.title + '\n' +
                          'Domain: ' + window.location.hostname);
                ";
                
                frame.ExecuteJavaScript(jsCode, "", 0);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"获取页面信息失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 执行同步测试脚本
        /// </summary>
        private void ExecuteSyncTestScript(IFBroSharpBrowser browser, IFBroSharpFrame frame)
        {
            try
            {
                string testJS = @"
                    console.log('同步浏览器测试脚本开始执行...');
                    
                    // 测试DOM操作
                    var testDiv = document.createElement('div');
                    testDiv.id = 'fbro-sync-test';
                    testDiv.style.cssText = 'position:fixed;top:10px;right:10px;background:#4CAF50;color:white;padding:10px;border-radius:5px;z-index:9999;font-family:Arial;';
                    testDiv.innerHTML = '同步浏览器测试 ✓<br>ID: ' + (window.FBroBrowserId || 'unknown');
                    document.body.appendChild(testDiv);
                    
                    // 3秒后移除测试元素
                    setTimeout(function() {
                        var testEl = document.getElementById('fbro-sync-test');
                        if (testEl) testEl.remove();
                    }, 3000);
                    
                    console.log('同步浏览器测试脚本执行完成');
                ";
                
                frame.ExecuteJavaScript(testJS, "", 0);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"执行测试脚本失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 清理同步浏览器资源
        /// </summary>
        private void CleanupSyncResources(IFBroSharpBrowser browser)
        {
            try
            {
                Console.WriteLine($"清理同步浏览器资源: {browser.GetIdentifier()}");
                
                // 在这里可以添加特定于同步浏览器的清理逻辑
                // 例如:保存状态、清理临时文件等
            }
            catch (Exception ex)
            {
                Console.WriteLine($"清理同步浏览器资源失败: {ex.Message}");
            }
        }

        #endregion
    }
}

基础用法

简单同步创建

csharp
private void CreateSyncBrowser_Click(object sender, EventArgs e)
{
    // 配置窗口信息
    FBroSharpWindowsInfo windows_info = new FBroSharpWindowsInfo
    {
        parent_window = this.Handle,
        x = 0,
        y = 0,
        width = this.ClientSize.Width,
        height = this.ClientSize.Height
    };

    // 创建浏览器事件回调类
    var browser_event = new SyncBrowserEvent(
        onCreated: browser => {
            Console.WriteLine($"同步浏览器创建完成: {browser.GetIdentifier()}");
        },
        onClosed: browser => {
            Console.WriteLine($"同步浏览器已关闭: {browser.GetIdentifier()}");
        },
        purpose: "基础同步浏览器"
    );
    
    // 创建同步创建任务
    FBroSharpTask createBrowserTask = new CreateBrowserTask(
        "https://www.baidu.com",
        windows_info,
        default,
        default,
        default,
        browser_event,
        default
    );
    
    // 投递任务到UI线程
    bool postTaskResult = FBroSharpTaskRunner.CefPostTask(FBroSharpThreadID.TID_UI, createBrowserTask);
    
    if (postTaskResult)
    {
        Console.WriteLine("浏览器创建任务成功投递到UI线程");
    }
    else
    {
        Console.WriteLine("浏览器创建任务投递失败");
    }
}

自定义任务类

csharp
/// <summary>
/// 同步创建浏览器的自定义任务类
/// </summary>
public class CreateBrowserTask : FBroSharpTask
{
    private readonly string url;
    private readonly FBroSharpWindowsInfo windowsInfo;
    private readonly FBroSharpBrowserSetting browserSetting;
    private readonly FBroSharpRequestContext requestContext;
    private readonly FBroSharpDictionaryValue extraInfo;
    private readonly FBroSharpBrowserEvent browserEvent;
    private readonly FBroSharpEventDisableControl eventDisableControl;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="url">初始加载的URL</param>
    /// <param name="windowsInfo">窗口信息配置</param>
    /// <param name="browserSetting">浏览器设置</param>
    /// <param name="requestContext">请求上下文</param>
    /// <param name="extraInfo">额外参数</param>
    /// <param name="browserEvent">浏览器事件回调</param>
    /// <param name="eventDisableControl">事件禁用控制</param>
    public CreateBrowserTask(
        string url, 
        FBroSharpWindowsInfo windowsInfo, 
        FBroSharpBrowserSetting browserSetting, 
        FBroSharpRequestContext requestContext, 
        FBroSharpDictionaryValue extraInfo, 
        FBroSharpBrowserEvent browserEvent, 
        FBroSharpEventDisableControl eventDisableControl)
    {
        this.url = url;
        this.windowsInfo = windowsInfo;
        this.browserSetting = browserSetting;
        this.requestContext = requestContext;
        this.extraInfo = extraInfo;
        this.browserEvent = browserEvent;
        this.eventDisableControl = eventDisableControl;
    }

    /// <summary>
    /// 执行同步创建浏览器的任务
    /// </summary>
    public override void Execute()
    {
        try
        {
            Console.WriteLine($"开始同步创建浏览器: {url}");
            
            // 调用同步创建方法并获取浏览器对象
            FBroSharpBrowser browser = FBroSharpControl.CreateSync(
                url, 
                windowsInfo, 
                browserSetting, 
                requestContext, 
                extraInfo, 
                browserEvent, 
                eventDisableControl
            );
            
            if (browser != null && browser.IsValid())
            {
                // 立即加载初始URL
                browser.GetMainFrame().LoadURL(url);
                
                // 可以在这里进行进一步的浏览器配置
                ConfigureBrowser(browser);
                
                Console.WriteLine($"同步创建浏览器成功,ID: {browser.GetIdentifier()}");
            }
            else
            {
                Console.WriteLine("同步创建浏览器失败,返回无效的浏览器实例");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"同步创建浏览器失败: {ex.Message}");
            Console.WriteLine($"堆栈跟踪: {ex.StackTrace}");
        }
    }
    
    /// <summary>
    /// 配置浏览器的其他属性
    /// </summary>
    /// <param name="browser">浏览器实例</param>
    private void ConfigureBrowser(FBroSharpBrowser browser)
    {
        try
        {
            // 设置缩放级别
            browser.SetZoomLevel(0.0);
            
            // 可以添加其他配置
            // browser.SetProxy("http://proxy.com:8080");
            
            Console.WriteLine($"浏览器配置完成: {browser.GetIdentifier()}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"配置浏览器失败: {ex.Message}");
        }
    }
}

高级用法

批量同步创建浏览器

csharp
public class BatchSyncBrowserCreator
{
    private readonly List<FBroSharpBrowser> browsers = new List<FBroSharpBrowser>();
    private int completedCount = 0;
    private readonly int totalCount;
    private readonly object lockObject = new object();

    public BatchSyncBrowserCreator(int count)
    {
        totalCount = count;
    }

    /// <summary>
    /// 批量创建多个同步浏览器
    /// </summary>
    public void CreateMultipleBrowsers()
    {
        string[] urls = {
            "https://www.baidu.com",
            "https://www.bing.com",
            "https://www.google.com",
            "https://www.yahoo.com"
        };

        for (int i = 0; i < totalCount; i++)
        {
            string url = urls[i % urls.Length];
            
            var task = new BatchCreateBrowserTask(url, i, this);
            
            bool result = FBroSharpTaskRunner.CefPostTask(FBroSharpThreadID.TID_UI, task);
            
            if (!result)
            {
                Console.WriteLine($"浏览器 {i} 任务投递失败");
            }
            
            // 添加小延迟避免同时创建过多浏览器
            System.Threading.Thread.Sleep(200);
        }
    }

    /// <summary>
    /// 浏览器创建完成回调
    /// </summary>
    public void OnBrowserCreated(FBroSharpBrowser browser, int index)
    {
        lock (lockObject)
        {
            browsers.Add(browser);
            completedCount++;
            
            Console.WriteLine($"浏览器 {index} 创建完成,总进度: {completedCount}/{totalCount}");
            
            if (completedCount == totalCount)
            {
                Console.WriteLine("所有同步浏览器创建完成");
                OnAllBrowsersCreated();
            }
        }
    }

    /// <summary>
    /// 所有浏览器创建完成处理
    /// </summary>
    private void OnAllBrowsersCreated()
    {
        Console.WriteLine($"成功创建 {browsers.Count} 个同步浏览器");
        
        // 可以在这里执行批量操作
        ExecuteBatchOperations();
    }

    /// <summary>
    /// 执行批量操作示例
    /// </summary>
    private void ExecuteBatchOperations()
    {
        for (int i = 0; i < browsers.Count; i++)
        {
            var browser = browsers[i];
            if (browser.IsValid())
            {
                // 为每个浏览器设置不同的标题
                string js = $@"document.title = '批量浏览器 {i + 1} - ' + document.title;";
                browser.GetMainFrame().ExecuteJavaScript(js, "", 0);
            }
        }
    }

    /// <summary>
    /// 获取所有创建的浏览器
    /// </summary>
    public List<FBroSharpBrowser> GetBrowsers()
    {
        lock (lockObject)
        {
            return new List<FBroSharpBrowser>(browsers);
        }
    }
}

/// <summary>
/// 批量创建浏览器任务
/// </summary>
public class BatchCreateBrowserTask : FBroSharpTask
{
    private readonly string url;
    private readonly int index;
    private readonly BatchSyncBrowserCreator creator;

    public BatchCreateBrowserTask(string url, int index, BatchSyncBrowserCreator creator)
    {
        this.url = url;
        this.index = index;
        this.creator = creator;
    }

    public override void Execute()
    {
        try
        {
            var windowsInfo = new FBroSharpWindowsInfo
            {
                parent_window = IntPtr.Zero,  // 创建弹窗
                x = 100 + (index * 50),       // 错开窗口位置
                y = 100 + (index * 50),
                width = 800,
                height = 600,
                window_name = $"同步浏览器 {index}"
            };

            // 创建专用的事件处理器
            var browserEvent = new SyncBrowserEvent(
                onCreated: browser => {
                    Console.WriteLine($"批量同步浏览器 {index} 创建完成");
                },
                purpose: $"批量浏览器-{index}"
            );
            
            // 添加额外信息
            var extraInfo = FBroSharpDictionaryValue.Create();
            extraInfo.SetInt("batch_index", index);
            extraInfo.SetString("batch_url", url);
            extraInfo.SetString("creation_time", DateTime.Now.ToString());
            
            FBroSharpBrowser browser = FBroSharpControl.CreateSync(
                url, 
                windowsInfo, 
                default, 
                default, 
                extraInfo, 
                browserEvent, 
                default
            );
            
            if (browser != null && browser.IsValid())
            {
                browser.GetMainFrame().LoadURL(url);
                
                // 通知创建完成
                creator.OnBrowserCreated(browser, index);
            }
            else
            {
                Console.WriteLine($"批量创建浏览器 {index} 失败:返回无效实例");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"批量创建浏览器 {index} 失败: {ex.Message}");
        }
    }
}

带配置的同步创建

csharp
public class AdvancedSyncBrowserCreator
{
    public static void CreateConfiguredBrowser(string url, BrowserConfig config)
    {
        var task = new ConfiguredBrowserTask(url, config);
        
        bool result = FBroSharpTaskRunner.CefPostTask(FBroSharpThreadID.TID_UI, task);
        
        if (!result)
        {
            throw new InvalidOperationException("无法投递浏览器创建任务到UI线程");
        }
    }
}

public class BrowserConfig
{
    public string CachePath { get; set; }
    public string ProxyUrl { get; set; }
    public string ProxyUser { get; set; }
    public string ProxyPassword { get; set; }
    public double ZoomLevel { get; set; } = 0.0;
    public bool IsPopup { get; set; } = false;
    public int Width { get; set; } = 1200;
    public int Height { get; set; } = 800;
    public Dictionary<string, object> CustomProperties { get; set; } = new Dictionary<string, object>();
}

public class ConfiguredBrowserTask : FBroSharpTask
{
    private readonly string url;
    private readonly BrowserConfig config;

    public ConfiguredBrowserTask(string url, BrowserConfig config)
    {
        this.url = url;
        this.config = config;
    }

    public override void Execute()
    {
        try
        {
            // 设置窗口信息
            var windowsInfo = new FBroSharpWindowsInfo
            {
                parent_window = config.IsPopup ? IntPtr.Zero : GetMainWindowHandle(),
                width = config.Width,
                height = config.Height,
                window_name = $"配置浏览器 - {url}"
            };

            // 设置请求上下文(独立缓存)
            FBroSharpRequestContext requestContext = null;
            if (!string.IsNullOrEmpty(config.CachePath))
            {
                var contextSet = new FBroSharpRequestContextSet
                {
                    cache_path = config.CachePath
                };
                requestContext = (FBroSharpRequestContext)FBroSharpRequestContext.CreateContext(contextSet);
            }

            // 创建配置化的事件处理器
            var browserEvent = new ConfiguredSyncBrowserEvent(config);

            // 设置额外信息
            var extraInfo = FBroSharpDictionaryValue.Create();
            extraInfo.SetString("config_cache_path", config.CachePath ?? "default");
            extraInfo.SetDouble("config_zoom_level", config.ZoomLevel);
            extraInfo.SetBool("config_is_popup", config.IsPopup);
            
            // 添加自定义属性
            foreach (var prop in config.CustomProperties)
            {
                switch (prop.Value)
                {
                    case string strValue:
                        extraInfo.SetString($"custom_{prop.Key}", strValue);
                        break;
                    case int intValue:
                        extraInfo.SetInt($"custom_{prop.Key}", intValue);
                        break;
                    case bool boolValue:
                        extraInfo.SetBool($"custom_{prop.Key}", boolValue);
                        break;
                    case double doubleValue:
                        extraInfo.SetDouble($"custom_{prop.Key}", doubleValue);
                        break;
                }
            }

            // 同步创建浏览器
            FBroSharpBrowser browser = FBroSharpControl.CreateSync(
                url,
                windowsInfo,
                default,
                requestContext,
                extraInfo,
                browserEvent,
                default
            );

            if (browser != null && browser.IsValid())
            {
                browser.GetMainFrame().LoadURL(url);
                Console.WriteLine($"配置浏览器创建成功: {url}");
            }
            else
            {
                Console.WriteLine($"配置浏览器创建失败: {url}");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"配置浏览器创建失败: {ex.Message}");
        }
    }

    private IntPtr GetMainWindowHandle()
    {
        // 获取主窗口句柄的逻辑
        return Process.GetCurrentProcess().MainWindowHandle;
    }
}

/// <summary>
/// 配置化的同步浏览器事件处理器
/// </summary>
public class ConfiguredSyncBrowserEvent : SyncBrowserEvent
{
    private readonly BrowserConfig config;

    public ConfiguredSyncBrowserEvent(BrowserConfig config) : base(purpose: "配置化浏览器")
    {
        this.config = config;
    }

    public override void OnAfterCreated(IFBroSharpBrowser browser, IFBroSharpDictionaryValue extrainfo)
    {
        base.OnAfterCreated(browser, extrainfo);
        
        // 应用配置
        ApplyConfiguration(browser);
    }

    /// <summary>
    /// 应用浏览器配置
    /// </summary>
    private void ApplyConfiguration(IFBroSharpBrowser browser)
    {
        try
        {
            // 应用缩放级别
            if (config.ZoomLevel != 0.0)
            {
                browser.SetZoomLevel(config.ZoomLevel);
            }

            // 应用代理设置
            if (!string.IsNullOrEmpty(config.ProxyUrl))
            {
                if (!string.IsNullOrEmpty(config.ProxyUser))
                {
                    browser.SetProxy(config.ProxyUrl, config.ProxyUser, config.ProxyPassword);
                }
                else
                {
                    browser.SetProxy(config.ProxyUrl);
                }
            }

            Console.WriteLine($"浏览器配置已应用: ID={browser.GetIdentifier()}");
            
            // 注入配置信息到页面
            string configJS = $@"
                window.FBroConfig = {{
                    zoomLevel: {config.ZoomLevel},
                    isPopup: {config.IsPopup.ToString().ToLower()},
                    cachePath: '{config.CachePath ?? "default"}',
                    customProperties: {Newtonsoft.Json.JsonConvert.SerializeObject(config.CustomProperties)}
                }};
                console.log('FBro配置已注入:', window.FBroConfig);
            ";
            
            browser.GetMainFrame().ExecuteJavaScript(configJS, "", 0);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"应用浏览器配置失败: {ex.Message}");
        }
    }
}

方法参数说明

FBroSharpTaskRunner.CefPostTask

语法:

csharp
bool CefPostTask(FBroSharpThreadID threadId, FBroSharpTask task)

参数:

参数类型说明
threadIdFBroSharpThreadID目标线程ID,同步创建使用TID_UI
taskFBroSharpTask要执行的任务实例

返回值:

类型说明
booltrue表示任务投递成功,false表示投递失败

FBroSharpControl.CreateSync

语法:

csharp
FBroSharpBrowser CreateSync(
    string url,
    FBroSharpWindowsInfo windowsInfo,
    FBroSharpBrowserSetting browserSetting,
    FBroSharpRequestContext requestContext,
    FBroSharpDictionaryValue extraInfo,
    FBroSharpBrowserEvent browserEvent,
    FBroSharpEventDisableControl eventDisableControl,
    string user_flag
)

参数:

参数类型说明
urlstring初始加载的URL
windowsInfoFBroSharpWindowsInfo窗口信息配置
browserSettingFBroSharpBrowserSetting浏览器设置(可选)
requestContextFBroSharpRequestContext请求上下文(可选)
extraInfoFBroSharpDictionaryValue额外参数(可选)
browserEventFBroSharpBrowserEvent浏览器事件回调
eventDisableControlFBroSharpEventDisableControl事件禁用控制(可选)
user_flagstring用户自定义浏览器标识符(可选)

返回值:

类型说明
FBroSharpBrowser创建成功的浏览器实例

user_flag在同步创建中的应用

同步创建中的标识管理

同步创建浏览器时,user_flag参数特别重要,因为它能让您立即标识和管理创建的浏览器实例:

csharp
/// <summary>
/// 同步创建带标识的浏览器任务
/// </summary>
public class SyncCreateBrowserWithFlagTask : FBroSharpTask
{
    private readonly string url;
    private readonly string userFlag;
    private readonly FBroSharpWindowsInfo windowsInfo;
    private readonly Action<FBroSharpBrowser, string> onSuccess;
    private readonly Action<string, Exception> onError;

    public SyncCreateBrowserWithFlagTask(
        string url, 
        string userFlag,
        FBroSharpWindowsInfo windowsInfo,
        Action<FBroSharpBrowser, string> onSuccess = null,
        Action<string, Exception> onError = null)
    {
        this.url = url;
        this.userFlag = userFlag;
        this.windowsInfo = windowsInfo;
        this.onSuccess = onSuccess;
        this.onError = onError;
    }

    public override void Execute()
    {
        try
        {
            // 创建额外信息,包含user_flag
            var extraInfo = FBroSharpDictionaryValue.Create();
            extraInfo.SetString("sync_user_flag", userFlag);
            extraInfo.SetString("sync_created_time", DateTime.Now.ToString());
            extraInfo.SetBool("is_sync_created", true);

            // 创建同步浏览器事件处理器
            var browserEvent = new SyncBrowserEvent(
                onCreated: browser => {
                    Console.WriteLine($"同步浏览器创建成功: {userFlag}");
                    onSuccess?.Invoke(browser, userFlag);
                },
                onClosed: browser => {
                    Console.WriteLine($"同步浏览器已关闭: {userFlag}");
                },
                purpose: $"同步浏览器-{userFlag}"
            );

            // 同步创建浏览器,指定user_flag
            FBroSharpBrowser browser = FBroSharpControl.CreateSync(
                url,
                windowsInfo,
                default,
                default,
                extraInfo,
                browserEvent,
                default,
                userFlag  // 关键:指定用户标识
            );

            if (browser != null && browser.IsValid())
            {
                browser.GetMainFrame().LoadURL(url);
                Console.WriteLine($"同步创建浏览器成功,标识: {userFlag},ID: {browser.GetIdentifier()}");
                
                // 立即验证标识是否可用
                var retrievedBrowser = FBroSharpBrowserListControl.GetBrowserFromFlag(userFlag);
                if (retrievedBrowser != null && retrievedBrowser.IsSame(browser))
                {
                    Console.WriteLine($"标识验证成功: {userFlag}");
                }
                else
                {
                    Console.WriteLine($"警告:标识验证失败: {userFlag}");
                }
            }
            else
            {
                throw new InvalidOperationException($"同步创建浏览器失败,返回无效实例: {userFlag}");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"同步创建浏览器异常: {userFlag} - {ex.Message}");
            onError?.Invoke(userFlag, ex);
        }
    }
}

同步批量创建管理器

csharp
/// <summary>
/// 同步批量创建浏览器管理器
/// 专门用于同步创建场景下的浏览器管理
/// </summary>
public class SyncBatchBrowserManager
{
    private readonly Dictionary<string, SyncBrowserInfo> syncBrowsers = new Dictionary<string, SyncBrowserInfo>();
    private readonly object lockObject = new object();

    public class SyncBrowserInfo
    {
        public string UserFlag { get; set; }
        public FBroSharpBrowser Browser { get; set; }
        public string Purpose { get; set; }
        public DateTime CreatedTime { get; set; }
        public string InitialUrl { get; set; }
        public bool IsCreated { get; set; }
        public Exception CreationError { get; set; }
    }

    /// <summary>
    /// 批量同步创建浏览器
    /// </summary>
    /// <param name="browserConfigs">浏览器配置列表</param>
    /// <returns>创建成功的浏览器数量</returns>
    public int BatchCreateSync(List<(string url, string userFlag, string purpose)> browserConfigs)
    {
        int successCount = 0;
        var tasks = new List<SyncCreateBrowserWithFlagTask>();

        // 准备所有任务
        for (int i = 0; i < browserConfigs.Count; i++)
        {
            var config = browserConfigs[i];
            
            // 确保user_flag唯一
            string uniqueFlag = $"{config.userFlag}_{DateTime.Now:yyyyMMddHHmmssffff}_{i}";

            var windowsInfo = new FBroSharpWindowsInfo
            {
                parent_window = IntPtr.Zero,
                x = 100 + (i * 60),
                y = 100 + (i * 60),
                width = 1000,
                height = 700,
                window_name = $"同步浏览器-{config.purpose}"
            };

            // 记录浏览器信息
            lock (lockObject)
            {
                syncBrowsers[uniqueFlag] = new SyncBrowserInfo
                {
                    UserFlag = uniqueFlag,
                    Purpose = config.purpose,
                    InitialUrl = config.url,
                    CreatedTime = DateTime.Now,
                    IsCreated = false
                };
            }

            var task = new SyncCreateBrowserWithFlagTask(
                config.url,
                uniqueFlag,
                windowsInfo,
                onSuccess: (browser, flag) => {
                    lock (lockObject)
                    {
                        if (syncBrowsers.ContainsKey(flag))
                        {
                            syncBrowsers[flag].Browser = browser;
                            syncBrowsers[flag].IsCreated = true;
                        }
                    }
                    Interlocked.Increment(ref successCount);
                },
                onError: (flag, error) => {
                    lock (lockObject)
                    {
                        if (syncBrowsers.ContainsKey(flag))
                        {
                            syncBrowsers[flag].CreationError = error;
                        }
                    }
                }
            );

            tasks.Add(task);
        }

        // 顺序投递任务到UI线程
        foreach (var task in tasks)
        {
            bool posted = FBroSharpTaskRunner.CefPostTask(FBroSharpThreadID.TID_UI, task);
            if (!posted)
            {
                Console.WriteLine("任务投递失败");
            }
            
            // 添加小延迟避免同时创建过多浏览器
            System.Threading.Thread.Sleep(100);
        }

        // 等待所有任务完成(简单实现,实际项目中可使用更复杂的同步机制)
        int maxWaitTime = 30000; // 30秒超时
        int waited = 0;
        while (successCount + GetErrorCount() < browserConfigs.Count && waited < maxWaitTime)
        {
            System.Threading.Thread.Sleep(100);
            waited += 100;
        }

        Console.WriteLine($"批量同步创建完成: 成功 {successCount}/{browserConfigs.Count}");
        PrintCreationSummary();

        return successCount;
    }

    /// <summary>
    /// 通过标识获取同步创建的浏览器
    /// </summary>
    /// <param name="userFlag">用户标识</param>
    /// <returns>浏览器实例</returns>
    public FBroSharpBrowser GetSyncBrowser(string userFlag)
    {
        lock (lockObject)
        {
            if (syncBrowsers.ContainsKey(userFlag) && syncBrowsers[userFlag].IsCreated)
            {
                return syncBrowsers[userFlag].Browser;
            }
        }

        // 从全局列表中获取
        return FBroSharpBrowserListControl.GetBrowserFromFlag(userFlag);
    }

    /// <summary>
    /// 批量操作同步创建的浏览器
    /// </summary>
    /// <param name="action">操作函数</param>
    public void BatchOperateSync(Action<FBroSharpBrowser, SyncBrowserInfo> action)
    {
        List<SyncBrowserInfo> browserList;
        
        lock (lockObject)
        {
            browserList = syncBrowsers.Values.Where(info => info.IsCreated).ToList();
        }

        foreach (var info in browserList)
        {
            try
            {
                if (info.Browser != null && info.Browser.IsValid())
                {
                    action(info.Browser, info);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"批量操作失败: {info.UserFlag} - {ex.Message}");
            }
        }
    }

    /// <summary>
    /// 设置所有同步浏览器的标题
    /// </summary>
    /// <param name="titlePrefix">标题前缀</param>
    public void SetAllBrowserTitles(string titlePrefix)
    {
        BatchOperateSync((browser, info) =>
        {
            string jsCode = $@"
                document.title = '{titlePrefix} - {info.Purpose} - ' + document.title;
                console.log('同步浏览器标题已更新: {info.UserFlag}');
            ";
            browser.GetMainFrame().ExecuteJavaScript(jsCode, "", 0);
        });
    }

    /// <summary>
    /// 关闭所有同步创建的浏览器
    /// </summary>
    public void CloseAllSyncBrowsers()
    {
        BatchOperateSync((browser, info) =>
        {
            Console.WriteLine($"关闭同步浏览器: {info.Purpose} ({info.UserFlag})");
            browser.CloseBrowser(true);
        });

        lock (lockObject)
        {
            syncBrowsers.Clear();
        }
    }

    /// <summary>
    /// 获取创建错误的数量
    /// </summary>
    /// <returns>错误数量</returns>
    private int GetErrorCount()
    {
        lock (lockObject)
        {
            return syncBrowsers.Values.Count(info => info.CreationError != null);
        }
    }

    /// <summary>
    /// 打印创建摘要
    /// </summary>
    private void PrintCreationSummary()
    {
        lock (lockObject)
        {
            int total = syncBrowsers.Count;
            int success = syncBrowsers.Values.Count(info => info.IsCreated);
            int errors = syncBrowsers.Values.Count(info => info.CreationError != null);
            int pending = total - success - errors;

            Console.WriteLine($"\n=== 同步创建浏览器摘要 ===");
            Console.WriteLine($"总数: {total}");
            Console.WriteLine($"成功: {success}");
            Console.WriteLine($"失败: {errors}");
            Console.WriteLine($"等待: {pending}");

            // 显示错误详情
            var errorBrowsers = syncBrowsers.Values.Where(info => info.CreationError != null).ToList();
            if (errorBrowsers.Any())
            {
                Console.WriteLine("\n失败详情:");
                foreach (var info in errorBrowsers)
                {
                    Console.WriteLine($"  {info.UserFlag}: {info.CreationError.Message}");
                }
            }

            Console.WriteLine("========================\n");
        }
    }

    /// <summary>
    /// 获取统计信息
    /// </summary>
    /// <returns>统计字典</returns>
    public Dictionary<string, object> GetStatistics()
    {
        lock (lockObject)
        {
            return new Dictionary<string, object>
            {
                ["total"] = syncBrowsers.Count,
                ["success"] = syncBrowsers.Values.Count(info => info.IsCreated),
                ["errors"] = syncBrowsers.Values.Count(info => info.CreationError != null),
                ["pending"] = syncBrowsers.Values.Count(info => !info.IsCreated && info.CreationError == null),
                ["flags"] = syncBrowsers.Keys.ToList()
            };
        }
    }
}

使用示例

csharp
// 使用同步批量创建管理器
private void UseSyncBatchManager()
{
    var manager = new SyncBatchBrowserManager();

    // 准备浏览器配置
    var configs = new List<(string url, string userFlag, string purpose)>
    {
        ("https://www.baidu.com", "search_baidu", "搜索测试"),
        ("https://www.bing.com", "search_bing", "搜索对比"),
        ("https://www.github.com", "dev_github", "开发工具"),
        ("https://www.stackoverflow.com", "dev_stackoverflow", "技术支持")
    };

    // 批量同步创建
    int successCount = manager.BatchCreateSync(configs);
    
    if (successCount > 0)
    {
        // 等待片刻让浏览器完全加载
        System.Threading.Thread.Sleep(2000);
        
        // 设置所有浏览器标题
        manager.SetAllBrowserTitles("FBro同步测试");
        
        // 通过标识获取特定浏览器进行操作
        var allFlags = manager.GetStatistics()["flags"] as List<string>;
        var baiduFlag = allFlags?.FirstOrDefault(f => f.Contains("search_baidu"));
        
        if (!string.IsNullOrEmpty(baiduFlag))
        {
            var baiduBrowser = manager.GetSyncBrowser(baiduFlag);
            if (baiduBrowser != null)
            {
                // 在百度浏览器中执行搜索
                string searchJS = @"
                    var searchInput = document.querySelector('#kw');
                    if (searchInput) {
                        searchInput.value = 'FBro浏览器测试';
                        searchInput.form.submit();
                    }
                ";
                baiduBrowser.GetMainFrame().ExecuteJavaScript(searchJS, "", 0);
                Console.WriteLine($"已在百度浏览器中执行搜索: {baiduFlag}");
            }
        }
        
        // 批量操作所有GitHub相关浏览器
        manager.BatchOperateSync((browser, info) =>
        {
            if (info.UserFlag.Contains("github"))
            {
                string githubJS = @"
                    document.body.style.border = '3px solid #28a745';
                    console.log('GitHub浏览器已标记: " + info.UserFlag + @"');
                ";
                browser.GetMainFrame().ExecuteJavaScript(githubJS, "", 0);
            }
        });
        
        // 打印统计信息
        var stats = manager.GetStatistics();
        Console.WriteLine($"同步创建统计: {Newtonsoft.Json.JsonConvert.SerializeObject(stats, Newtonsoft.Json.Formatting.Indented)}");
        
        // 演示标识验证
        foreach (var flag in allFlags ?? new List<string>())
        {
            var browser = FBroSharpBrowserListControl.GetBrowserFromFlag(flag);
            if (browser != null)
            {
                Console.WriteLine($"验证成功 - 标识: {flag}, 浏览器ID: {browser.GetIdentifier()}");
            }
        }
    }
    else
    {
        Console.WriteLine("没有成功创建任何同步浏览器");
    }
}

/// <summary>
/// 演示单个同步浏览器的完整创建和管理流程
/// </summary>
private void DemonstrateCompleteSyncFlow()
{
    // 1. 生成标识
    string userFlag = SyncBrowserFlagGenerator.GenerateSyncFlag("demo", "complete");
    Console.WriteLine($"生成的同步标识: {userFlag}");

    // 2. 创建监控器
    var monitor = new SyncCreationMonitor();

    // 3. 配置窗口信息
    var windowsInfo = new FBroSharpWindowsInfo
    {
        parent_window = IntPtr.Zero,
        x = 200,
        y = 200,
        width = 1000,
        height = 700,
        window_name = $"完整流程演示-{userFlag}"
    };

    // 4. 创建增强任务
    var task = new EnhancedSyncCreateTask(
        "https://www.example.com",
        userFlag,
        windowsInfo,
        monitor,
        onSuccess: (browser, flag) =>
        {
            Console.WriteLine($"浏览器创建成功回调: {flag}");
            
            // 立即验证和操作
            if (SyncFlagValidator.ValidateSyncCreatedBrowser(browser, flag))
            {
                // 注入测试脚本
                string testJS = @"
                    console.log('完整流程演示浏览器已就绪');
                    document.title = '完整流程演示 - " + flag + @"';
                    
                    // 添加成功标记
                    var successDiv = document.createElement('div');
                    successDiv.innerHTML = '✅ FBro同步创建成功<br>标识: " + flag + @"';
                    successDiv.style.cssText = 'position:fixed;top:10px;right:10px;background:#4CAF50;color:white;padding:15px;border-radius:8px;z-index:9999;font-family:Arial;';
                    document.body.appendChild(successDiv);
                ";
                browser.GetMainFrame().ExecuteJavaScript(testJS, "", 0);
            }
        },
        onError: (flag, error) =>
        {
            Console.WriteLine($"浏览器创建失败回调: {flag} - {error.Message}");
        }
    );

    // 5. 投递任务
    bool posted = FBroSharpTaskRunner.CefPostTask(FBroSharpThreadID.TID_UI, task);
    
    if (posted)
    {
        Console.WriteLine("完整流程演示任务已投递");
        
        // 6. 等待并检查结果
        System.Threading.Thread.Sleep(3000);
        
        var stats = monitor.GetStatistics();
        Console.WriteLine(stats.ToString());
        
        // 7. 验证浏览器是否可通过标识获取
        var retrievedBrowser = FBroSharpBrowserListControl.GetBrowserFromFlag(userFlag);
        if (retrievedBrowser != null && retrievedBrowser.IsValid())
        {
            Console.WriteLine($"✅ 完整流程演示成功 - 浏览器可通过标识 {userFlag} 获取");
        }
        else
        {
            Console.WriteLine($"❌ 完整流程演示失败 - 无法通过标识 {userFlag} 获取浏览器");
        }
    }
    else
    {
        Console.WriteLine("完整流程演示任务投递失败");
    }
}

## 线程ID说明

| 线程ID | 说明 |
|--------|------|
| `TID_UI` | UI线程,用于同步创建浏览器 |
| `TID_IO` | IO线程,处理网络请求 |
| `TID_FILE` | 文件线程,处理文件操作 |
| `TID_RENDERER` | 渲染线程,处理页面渲染 |

## 使用注意事项

### 1. 线程安全
- **UI线程要求**:同步创建必须在UI线程中执行
- **任务投递**:使用`CefPostTask`确保在正确的线程中执行
- **避免阻塞**:不要在主线程中直接调用同步创建

### 2. 错误处理
```csharp
public override void Execute()
{
    try
    {
        FBroSharpBrowser browser = FBroSharpControl.CreateSync(/* 参数 */);
        
        // 验证浏览器实例
        if (browser == null || !browser.IsValid())
        {
            Console.WriteLine("同步创建返回无效的浏览器实例");
            return;
        }
        
        // 成功处理逻辑
        Console.WriteLine($"同步创建成功: {browser.GetIdentifier()}");
    }
    catch (Exception ex)
    {
        // 记录错误日志
        Console.WriteLine($"同步创建失败: {ex.Message}");
        
        // 可以在这里添加重试逻辑或通知机制
        NotifyCreationFailed(ex);
    }
}

3. 资源管理

csharp
public override void Execute()
{
    FBroSharpRequestContext requestContext = null;
    try
    {
        // 创建资源
        requestContext = CreateRequestContext();
        
        FBroSharpBrowser browser = FBroSharpControl.CreateSync(/* 参数 */);
        
        // 使用浏览器
        if (browser != null && browser.IsValid())
        {
            // 执行操作
        }
    }
    finally
    {
        // 清理资源
        requestContext?.Dispose();
    }
}

最佳实践

  1. 任务封装:将创建逻辑封装在自定义任务类中
  2. 错误处理:始终包含try-catch进行异常处理
  3. 参数验证:在Execute方法中验证必要参数
  4. 实例验证:检查返回的浏览器实例是否有效
  5. 资源释放:正确管理创建的资源对象
  6. 状态跟踪:对于批量创建,实现进度跟踪机制
  7. 事件处理器优化:为同步创建场景创建专门的事件处理器
  8. 同步标识管理:在同步创建场景下合理使用user_flag进行浏览器管理

同步创建中的user_flag最佳实践

1. 立即验证机制

csharp
/// <summary>
/// 同步创建后立即验证user_flag
/// </summary>
public static class SyncFlagValidator
{
    /// <summary>
    /// 验证同步创建的浏览器标识
    /// </summary>
    /// <param name="browser">创建的浏览器实例</param>
    /// <param name="userFlag">预期的用户标识</param>
    /// <returns>验证结果</returns>
    public static bool ValidateSyncCreatedBrowser(FBroSharpBrowser browser, string userFlag)
    {
        if (browser == null || !browser.IsValid())
        {
            Console.WriteLine($"同步创建验证失败:浏览器实例无效 ({userFlag})");
            return false;
        }

        // 尝试通过标识获取浏览器
        var retrievedBrowser = FBroSharpBrowserListControl.GetBrowserFromFlag(userFlag);
        if (retrievedBrowser == null)
        {
            Console.WriteLine($"同步创建验证失败:无法通过标识获取浏览器 ({userFlag})");
            return false;
        }

        // 验证是否为同一浏览器实例
        if (!browser.IsSame(retrievedBrowser))
        {
            Console.WriteLine($"同步创建验证失败:浏览器实例不匹配 ({userFlag})");
            return false;
        }

        Console.WriteLine($"同步创建验证成功:{userFlag}");
        return true;
    }
}

2. 同步创建专用标识生成器

csharp
/// <summary>
/// 同步创建专用的标识生成器
/// </summary>
public static class SyncBrowserFlagGenerator
{
    private static int syncCounter = 0;
    private static readonly object counterLock = new object();

    /// <summary>
    /// 生成同步创建专用标识
    /// </summary>
    /// <param name="purpose">用途</param>
    /// <param name="category">分类</param>
    /// <returns>同步标识</returns>
    public static string GenerateSyncFlag(string purpose, string category = "sync")
    {
        lock (counterLock)
        {
            syncCounter++;
            string timestamp = DateTime.Now.ToString("yyyyMMddHHmmssffff");
            return $"sync_{category}_{purpose}_{timestamp}_{syncCounter:D4}".ToLower();
        }
    }

    /// <summary>
    /// 生成批量同步标识
    /// </summary>
    /// <param name="batchId">批次ID</param>
    /// <param name="index">索引</param>
    /// <param name="purpose">用途</param>
    /// <returns>批量同步标识</returns>
    public static string GenerateBatchSyncFlag(string batchId, int index, string purpose)
    {
        string timestamp = DateTime.Now.ToString("yyyyMMddHHmmssffff");
        return $"batch_{batchId}_{purpose}_{timestamp}_{index:D3}".ToLower();
    }

    /// <summary>
    /// 重置计数器(测试用)
    /// </summary>
    public static void ResetCounter()
    {
        lock (counterLock)
        {
            syncCounter = 0;
        }
    }
}

3. 同步创建状态监控

csharp
/// <summary>
/// 同步创建状态监控器
/// </summary>
public class SyncCreationMonitor
{
    private readonly Dictionary<string, SyncCreationStatus> creationStatuses = new Dictionary<string, SyncCreationStatus>();
    private readonly object lockObject = new object();

    public class SyncCreationStatus
    {
        public string UserFlag { get; set; }
        public DateTime StartTime { get; set; }
        public DateTime? CompletedTime { get; set; }
        public bool IsSuccess { get; set; }
        public Exception Error { get; set; }
        public FBroSharpBrowser Browser { get; set; }
        public TimeSpan? Duration => CompletedTime?.Subtract(StartTime);
    }

    /// <summary>
    /// 开始监控同步创建
    /// </summary>
    /// <param name="userFlag">用户标识</param>
    public void StartMonitoring(string userFlag)
    {
        lock (lockObject)
        {
            creationStatuses[userFlag] = new SyncCreationStatus
            {
                UserFlag = userFlag,
                StartTime = DateTime.Now
            };
        }
    }

    /// <summary>
    /// 完成监控(成功)
    /// </summary>
    /// <param name="userFlag">用户标识</param>
    /// <param name="browser">创建的浏览器</param>
    public void CompleteSuccess(string userFlag, FBroSharpBrowser browser)
    {
        lock (lockObject)
        {
            if (creationStatuses.ContainsKey(userFlag))
            {
                var status = creationStatuses[userFlag];
                status.CompletedTime = DateTime.Now;
                status.IsSuccess = true;
                status.Browser = browser;
            }
        }
    }

    /// <summary>
    /// 完成监控(失败)
    /// </summary>
    /// <param name="userFlag">用户标识</param>
    /// <param name="error">错误信息</param>
    public void CompleteError(string userFlag, Exception error)
    {
        lock (lockObject)
        {
            if (creationStatuses.ContainsKey(userFlag))
            {
                var status = creationStatuses[userFlag];
                status.CompletedTime = DateTime.Now;
                status.IsSuccess = false;
                status.Error = error;
            }
        }
    }

    /// <summary>
    /// 获取创建统计
    /// </summary>
    /// <returns>统计信息</returns>
    public CreationStatistics GetStatistics()
    {
        lock (lockObject)
        {
            var stats = new CreationStatistics();
            stats.TotalCount = creationStatuses.Count;
            stats.SuccessCount = creationStatuses.Values.Count(s => s.IsSuccess);
            stats.ErrorCount = creationStatuses.Values.Count(s => s.CompletedTime.HasValue && !s.IsSuccess);
            stats.PendingCount = creationStatuses.Values.Count(s => !s.CompletedTime.HasValue);
            
            if (stats.SuccessCount > 0)
            {
                var successfulCreations = creationStatuses.Values.Where(s => s.IsSuccess && s.Duration.HasValue);
                stats.AverageCreationTime = TimeSpan.FromMilliseconds(
                    successfulCreations.Average(s => s.Duration.Value.TotalMilliseconds)
                );
            }

            return stats;
        }
    }

    public class CreationStatistics
    {
        public int TotalCount { get; set; }
        public int SuccessCount { get; set; }
        public int ErrorCount { get; set; }
        public int PendingCount { get; set; }
        public TimeSpan AverageCreationTime { get; set; }
        public double SuccessRate => TotalCount > 0 ? (double)SuccessCount / TotalCount * 100 : 0;

        public override string ToString()
        {
            return $@"
=== 同步创建统计 ===
总数: {TotalCount}
成功: {SuccessCount}
失败: {ErrorCount}
等待: {PendingCount}
成功率: {SuccessRate:F2}%
平均创建时间: {AverageCreationTime.TotalMilliseconds:F0}ms
==================";
        }
    }
}

4. 增强的同步创建任务

csharp
/// <summary>
/// 增强版同步创建任务,包含完整的user_flag管理
/// </summary>
public class EnhancedSyncCreateTask : FBroSharpTask
{
    private readonly string url;
    private readonly string userFlag;
    private readonly FBroSharpWindowsInfo windowsInfo;
    private readonly SyncCreationMonitor monitor;
    private readonly Action<FBroSharpBrowser, string> onSuccess;
    private readonly Action<string, Exception> onError;

    public EnhancedSyncCreateTask(
        string url,
        string userFlag,
        FBroSharpWindowsInfo windowsInfo,
        SyncCreationMonitor monitor = null,
        Action<FBroSharpBrowser, string> onSuccess = null,
        Action<string, Exception> onError = null)
    {
        this.url = url;
        this.userFlag = userFlag;
        this.windowsInfo = windowsInfo;
        this.monitor = monitor;
        this.onSuccess = onSuccess;
        this.onError = onError;
    }

    public override void Execute()
    {
        // 开始监控
        monitor?.StartMonitoring(userFlag);

        try
        {
            // 预验证标识
            var validation = BrowserFlagValidator.ValidateFlag(userFlag);
            if (!validation.IsValid)
            {
                throw new ArgumentException($"标识格式无效: {string.Join(", ", validation.Errors)}");
            }

            // 确保标识唯一
            if (!BrowserFlagManager.IsUnique(userFlag))
            {
                throw new InvalidOperationException($"标识已存在: {userFlag}");
            }

            // 创建额外信息
            var extraInfo = FBroSharpDictionaryValue.Create();
            extraInfo.SetString("sync_user_flag", userFlag);
            extraInfo.SetString("sync_created_time", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
            extraInfo.SetBool("is_sync_created", true);
            extraInfo.SetString("sync_url", url);

            // 创建事件处理器
            var browserEvent = new EnhancedSyncBrowserEvent(userFlag, url);

            // 同步创建浏览器
            Console.WriteLine($"开始同步创建浏览器: {userFlag}");
            
            FBroSharpBrowser browser = FBroSharpControl.CreateSync(
                url,
                windowsInfo,
                default,
                default,
                extraInfo,
                browserEvent,
                default,
                userFlag
            );

            // 验证创建结果
            if (browser == null || !browser.IsValid())
            {
                throw new InvalidOperationException($"同步创建返回无效浏览器实例: {userFlag}");
            }

            // 立即验证标识
            if (!SyncFlagValidator.ValidateSyncCreatedBrowser(browser, userFlag))
            {
                throw new InvalidOperationException($"同步创建标识验证失败: {userFlag}");
            }

            // 加载URL
            browser.GetMainFrame().LoadURL(url);

            // 成功回调
            Console.WriteLine($"同步创建浏览器成功: {userFlag} (ID: {browser.GetIdentifier()})");
            monitor?.CompleteSuccess(userFlag, browser);
            onSuccess?.Invoke(browser, userFlag);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"同步创建浏览器失败: {userFlag} - {ex.Message}");
            monitor?.CompleteError(userFlag, ex);
            onError?.Invoke(userFlag, ex);
        }
    }
}

/// <summary>
/// 增强版同步浏览器事件处理器
/// </summary>
public class EnhancedSyncBrowserEvent : SyncBrowserEvent
{
    private readonly string userFlag;
    private readonly string originalUrl;

    public EnhancedSyncBrowserEvent(string userFlag, string originalUrl) 
        : base(purpose: $"增强同步-{userFlag}")
    {
        this.userFlag = userFlag;
        this.originalUrl = originalUrl;
    }

    public override void OnAfterCreated(IFBroSharpBrowser browser, IFBroSharpDictionaryValue extrainfo)
    {
        base.OnAfterCreated(browser, extrainfo);

        // 注入增强信息
        string enhancedJS = $@"
            window.FBroSyncEnhanced = {{
                userFlag: '{userFlag}',
                originalUrl: '{originalUrl}',
                createdTime: '{DateTime.Now:yyyy-MM-dd HH:mm:ss}',
                browserId: {browser.GetIdentifier()},
                isEnhancedSync: true,
                
                // 实用工具函数
                getInfo: function() {{
                    return {{
                        flag: this.userFlag,
                        url: this.originalUrl,
                        created: this.createdTime,
                        id: this.browserId
                    }};
                }},
                
                logInfo: function() {{
                    console.log('FBro增强同步浏览器信息:', this.getInfo());
                }}
            }};
            
            // 自动记录信息
            window.FBroSyncEnhanced.logInfo();
        ";

        browser.GetMainFrame().ExecuteJavaScript(enhancedJS, "", 0);
    }
}

与异步创建的对比

特性同步创建异步创建
执行线程必须在UI线程任意线程
返回方式立即返回浏览器实例通过回调获取
复杂度需要任务投递机制直接调用
适用场景需要立即使用浏览器一般创建场景
性能影响可能阻塞UI线程不阻塞主线程
错误处理可立即捕获异常通过事件处理

实际应用场景

  1. 自动化测试:需要批量创建多个浏览器进行并行测试
  2. 数据采集:同时打开多个页面进行数据抓取
  3. 监控系统:创建多个浏览器监控不同网站
  4. 演示程序:需要精确控制浏览器创建时机的演示应用
  5. 开发调试:快速创建测试浏览器进行功能验证

相关文档

如果文档对您有帮助,欢迎 请喝咖啡 ☕ | 软件发布 | 源码购买